package com.jmp.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.gexin.fastjson.JSON;
import com.github.vioao.wechat.utils.StringUtils;
import com.jmp.api.dto.MessageDto;
import com.jmp.api.dto.MessagePushDto;
import com.jmp.api.dto.UserMsgType;
import com.jmp.api.service.*;
import com.jmp.base.dto.*;
import lombok.extern.slf4j.Slf4j;
import one.stand.dto.ConvertUtils;
import one.stand.dto.UserDto;
import one.stand.enums.LoginEnum;
import one.stand.mapper.ChatContentMapperExt;
import one.stand.mapper.ChatMapper;
import one.stand.mapper.ChatMapperExt;
import one.stand.model.Chat;
import one.stand.model.ChatContent;
import one.stand.model.CompanyAccount;
import one.stand.service.user.TokenService;
import one.stand.service.user.UserAdminService;
import one.stand.util.DateUtil;
import one.stand.util.HttpUtil2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

@Service
@Slf4j
public class ImServiceImpl implements ImService {

    private String req_url = "https://api.weixin.qq.com/tcb/databaseadd?access_token=%s";
    private String req_query = "db.collection(\"user_msg\").add({data: %s})";

    @Autowired
    private WechatBaseService wechatBaseService;
    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private ChatMapperExt chatMapperExt;
    @Autowired
    private ChatMapper chatMapper;
    @Autowired
    private ChatContentMapperExt chatContentMapperExt;
    @Autowired
    private MessageService messageService;
    @Autowired
    private MessageWxService messageWxService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private CompanyAccountService companyAccountService;

    @Override
    @Transactional
    public ChatContent send(ImSendRequest request) {
        // 会话ID
        String cid = request.getConId();
        if(StringUtils.isBlank(cid)) {//根据聊天人
            Chat chat = chatMapperExt.getByTargetUserId(request.getId(), request.getTargetUserId());
            if(Objects.nonNull(chat)) {
                cid = chat.getCid();
            }
        }

        Date date = new Date();
        UserDto user = userAdminService.get(request.getId());
        //聊天内容
        Chat chat = new Chat();
        chat.setCid(cid);
        chat.setLastcontent("img".equals(request.getImType()) ? "图片" : request.getContent());
        chat.setLasttime(date.getTime());
        //首次会话生成历史记录
        if (StringUtils.isBlank(cid)) {
            cid = UUID.randomUUID().toString();
            chat.setCid(cid);
            chat.setCtime(date);
            //我的记录
            UserDto targetUser = userAdminService.get(request.getTargetUserId());
            chat.setUserid(request.getId().longValue());
            chat.setTargetUserId(request.getTargetUserId().longValue());
            chat.setTargetAvatar(targetUser.getUserImg());
            chat.setTargetUsername(targetUser.getName());
            chatMapper.insertSelective(chat);
            //对方记录
            chat.setId(null);
            chat.setUserid(request.getTargetUserId().longValue());
            chat.setTargetUserId(request.getId().longValue());
            chat.setTargetAvatar(user.getUserImg());
            chat.setTargetUsername(user.getName());
            chatMapper.insertSelective(chat);
        } else {
            //根据cid更新最后一次聊天内容
            chatMapperExt.updateByCid(chat);
        }


        //保存聊天记录
        ChatContent chatContent = new ChatContent();
        chatContent.setCid(cid);
        chatContent.setCtime(date);
        chatContent.setContent(request.getContent());
        chatContent.setUserid(request.getId().longValue());
        chatContent.setAvatar(user.getUserImg());
        chatContent.setUsername(user.getName());
        chatContent.setType(request.getImType());
        chatContentMapperExt.insertSelective(chatContent);


        this.sendMsg(request, user);
        return chatContent;
    }

    @Override
    public List<Chat> getImChat(Integer userId) {
        return chatMapperExt.getImChat(userId);
    }

    @Override
    public ImResponse getChatContent(ImRequest request) {
        log.info("getTargetUserId={},id={}", request.getTargetUserId(), request.getId());
        ImResponse response = ImResponse
                .builder()
                .tUserId(request.getTargetUserId())
                .build();
        Chat chat = chatMapperExt.getByTargetUserId(request.getId(), request.getTargetUserId());
        if (chat == null) {
            UserDto user = userAdminService.get(request.getTargetUserId());
            response.setUserName(user.getName());
            response.setAvatar(user.getUserImg());
            return response;
        }
        response.setAvatar(chat.getTargetAvatar());
        response.setUserName(chat.getTargetUsername());

        List<ChatContent> chatContents = chatContentMapperExt.getChatContent(chat.getCid());
        List<ImResponse.ChatContent> chatContentList = ConvertUtils.list(chatContents, chatContent -> ImResponse.ChatContent.builder()
                .id(chatContent.getId())
                .cid(chatContent.getCid())
                .userid(chatContent.getUserid())
                .avatar(chatContent.getAvatar())
                .username(chatContent.getUsername())
                .type(chatContent.getType())
                .content(chatContent.getContent())
                .ctime(chatContent.getCtime())
                .build());

        response.setChatContentList(chatContentList);
        return response;
    }

    /**
     * to do
     *
     * @param imSendRequest
     * @param user
     */
    private void sendMsg(ImSendRequest imSendRequest, UserDto user) {
        // 聊天内容是联系我
        if ("contact".equals(imSendRequest.getImType())) {
            imSendRequest.setContent(user.getName() + "xxx希望与您会谈，请及时联系我");
        }

        if (tokenService.hasLoginStatus(imSendRequest.getTargetUserId(), LoginEnum.CRM)) { // app推送
            MessagePushDto pushRequest = MessagePushDto.builder()
                    .type(MessagePushType.UNREAD_MESSAGE)
                    .toId(imSendRequest.getTargetUserId())
                    .fillData(new String[]{imSendRequest.getContent()})
                    .title(user.getName())
                    .build();
            messageService.push(pushRequest);
//        } else if (tokenService.isLoginStatus(imSendRequest.getTargetUserId(), LoginEnum.USER)) { // 小程序在线发送云数据库
//            UserMsgType type = UserMsgType.builder()
//                    .toUser(user.getUserId() + "")
//                    .userId(imSendRequest.getTargetUserId())
//                    .build();
//            sendToMiniAppYun(imSendRequest.getCompanyKey(), type);
        } else { // 小程序服务通知
            String[] arr = {user.getName(), DateUtil.getDay(), imSendRequest.getContent()};
            MessageDto messageDto = MessageDto.builder()
                    .noticeEnums(MessageWxNoticeEnums.UNREAD_MESSAGE_USER)
                    .accountType(LoginEnum.USER)
                    .toUserId(imSendRequest.getTargetUserId())
                    .companyKey(imSendRequest.getCompanyKey())
                    .fillData(arr)
                    .parameter("?toUser=" + user.getUserId())
                    .build();
            messageWxService.sendTemplateWx(messageDto);
        }
    }

    /**
     * 发送到对应小程序云数据库.
     */
    private void sendToMiniAppYun(String companyKey, UserMsgType userMsgType) {
        String evn = "huayuan01";
        if (StringUtils.isBlank(companyKey)) {
            log.info("没有获取到companykey", companyKey);
            companyKey = "huayuan";
        }
        if ("quanjing".equals(companyKey)) {
            evn = "quanjing01";
        }
        CompanyAccount companyAccount = companyAccountService.getDefaultIfNull(companyKey, LoginEnum.USER);
        String token = wechatBaseService.getWxToken(companyAccount.getAppId(), companyAccount.getAppSecret());
        JSONObject json = new JSONObject();
        json.put("env", evn);
        json.put("query", String.format(req_query, JSON.toJSONString(userMsgType)));
        log.info("param={}", json.toJSONString());
        try {
            String result = HttpUtil2.post(String.format(req_url, token), json.toJSONString());
            log.info("result={}", result);
        } catch (IOException e) {
            log.error("send msg to mini app error", e);
        }
    }

}
